public class Blog {
    // **** 博客系统 *****
    // 基本情况: 主要有四个页面
    // 1.博客列表. 显示出当前网站上都有哪些博客
    // 2.博客详情页. 点击列表上的某个博客,就能进入对应的详情页(显示出博客的具体内容)
    // 3.博客编辑页, 可以让用户输入博客内容, 并且发送到服务器
    // 4.登录页.

    // 对应的前端代码都已经准备好了

    //当下要完成的任务:
    // 1) 实现博客列表页.
    //   让页面从服务器拿到博客数据(数据库)
    // 2) 实现博客详情页
    //    点击博客详情的时候,可以从服务器拿到博客的完整数据
    // 3) 实现登录功能
    // 4) 实现强制要求登录
    //    (当前处于未登录状态, 其他的页面, 博客列表,博客详情页,博客编辑.. 就会强制跳转到登录页, 要求用户登录之后才能使用)
    // 5) 实现显示用户信息
    //  从服务器获取到, 博客列表页,拿到的是当前登录的用户的信息, 博客详情页,拿到的是文章作者的信息
    // 6) 实现退出登录
    // 7) 实现发布博客
    //    (在博客编辑页, 输入看文章标题和内容后, 点击发布, 就能把这个数据上传到服务器上 并 保存)

    // 准备工作 :
    // 1) 创建项目, 引入依赖, 把当前这些前端页面导入到项目当中
    // 2) 数据库设计
    //    设计好对应的表结构, 并且把数据库相关的代码, 也进行封装
    //     a) 找到实体
                // 博客 (blog表)
                // 用户 (user表)
    //     b) 确认实体之间的关系
    //          // 一对多 (一个博客只能属于一个用户, 一个用户可以发布多个博客)
    //      (在 博客表中引入 userId 这样的 属性)
    // 考虑两个表里面的内容
    // blog (blogId , title, content, postTime, userId)
    // user (userId, username, password)
    // 接下来把数据库操作的代码进行封装
    // 创建一个 model 包
    // (解释一下这个 model , 进行网站开发的时候, 一种常见的代码组织结构,MVC结构)
    // M 就是model: 操作数据的代码
    // V 就是view: 操作/构造界面的代码
    // C 就是controller: 业务逻辑, 处理前端请求

    // 再 下一步 就是 创建 实体类
    // 每一个表, (大部份表)都需要搞一个专门的 类 来表示
    // 表里的一条数据, 就会对应到这个类的对象

    // 实体类搞定之后 还需要创建两个类
    // 来完成对博客系统的和 用户表 增删改查操作
    // BlogDao  和 UserDao
    // 解释一下什么是 Dao => Data Access Object  (数据访问对象) (通过这两个类的对象,来完成针对数据库表的操作)

    // 接下来写代码,, 写一个复杂的代码往往是需要理清思路 (为了实现这个代码, 要写哪些类, 要实现哪个方法,方法的具体细节可以先不管)

    // 接下来获取博客列表页
    // 在博客列表页加载的时候, 通过 ajax 给服务器发起请求
    // 从服务器(数据库) 这里 拿到博客列表数据, 并且显示到页面上.

    // 第一步: 约定前后端交互接口
    // 请求: 约定使用 GET 请求 , 路径 /blog
    // 响应 : HTTP/1.1 200 OK
    //       Content-Type: application/json
    //       (下面是body 部分)
    //      [
    //       {
    //          blogId: 1,
    //          title: "这是标题",
    //          content: "这是正文",
    //          postTime: "2024-01-18 18:00:00",
    //          userId: 1
    //       }
    //       {
    //             ....... (这是一个数组, 可以包含多个记录)
    //        }
    //      ]
    // 这里面前后端交互接口的约定方式 是随心所欲的~~

    // 接下来进入 服务器, 让服务器能够处理这个请求

    // 接下来 再让前端代码 处理上述响应, 构造成 html 片段, 显示到页面上
    // 构造页面的过程 还是前面的几个 api
    // querySelector: 获取页面已有的元素
    // createElement: 创建新的元素
    // .innerHtml: 设置元素里的内容
    // .className: 设置元素的 class 属性
    // appendChild: 把这个元素添加到另一个元素的末尾.

    // 接下来是第二个功能, 实现一个博客详情页
    // (点击不同的博客,跳转过去之后, 都会带有不同的 blogId 的 query string)
    // (后续在博客详情页中, 就可以也给服务器发起 ajax 请求, 根据这里的 blogId, 查询数据库中, 博客的具体内容 在返回
    //  前端还是得把得到的数据给构造到页面上)

    // 1. 还是先约定 前后端交互的接口
    // 请求 GET/ blog?blog=1
    // 响应
    // HTTP/1.1 200 OK
    // Content-Type: application/json
    // (body 部分)
    // [
    //      {
    //         blogId:1,
    //         title: "这是第一篇博客",
    //         content:"这是博客正文",
    //         postTime : "2023-11-07 20:20:00",
    //         userId: 1
    //      }
    //    ]
    // 这个请求是希望在博客详情页的时候, 通过 ajax 发给服务器

    // 第二部: 让前端代码 通过 ajax 发起请求
    // (会遇到一个问题, 发起ajax 请求的时候 要带有 blogId~, blogId 当前就处于 博客详情页 的 url 中)
    // 这里可以通过 location.search 方式 拿到 页面当中 url 中的 query string

    // 第三步 让服务器处理这个请求
    //  因为这里给的路径还是 blog 路径 所以还是用 BlogServlet 来处理
    // 一个路径对应到一个 servlet
    // 当前是使用一个 servlet 处理两种请求
    // 博客列表页 不带有 query sting
    // 博客详情页 带有 query string
    // 就根据 query string 是否存在的情况来区分是那种请求, 分别返回不同的数据即可

    // 第四步, 前端拿到响应之后, 前端把这个响应构造成html 片段
    // 返回的数据就行如 上面格式的数据
    // 就是前端代码回调函数的blog (body)
    // 由于响应中 带有 Content-Type: application/json
    // jquery 自动帮我们把字符串转换成了 js 对象了
    // 所以 直接通过 . 的方式就可以访问属性

    // (写完代码之后 再点击某个博客, 就可以看到 有的博客里面的详情页, 还是之前旧的内容, 这是由于浏览器缓存引起的)
    // (我们的浏览器在加载页面的时候是通过网络获取的(网络比较慢),浏览器有的时候就会把已经加载过的页面,在本地硬盘中保存一份.
    // 后续在访问同一个页面, 就不需要通过网络加载, 直接加载本地硬盘的一份.(这所以有这种情况, 是因为 默认认为html 出现修改的概率比较低))
    // 这种问题 刷新一下就可以了

    // 还有一个问题, 当前博客详情页, 虽然能够显示出博客正文了,但是显示的是正文的 markdown 原始数据
    // 作为博客网站, 正确的做法应该是显示出 markdown 渲染后的效果
    // 此处的渲染还是通过第三方库 .(editor.md)
    // 在 editor.md 官方文档上 给出了具体的例子,来完成上述操作

    // 第三个功能 就是实现登录
    // 大体步骤跟上面的情况差不多
    // 也是 四步
    // 登录页面 在输入框中填写 用户名 和密码
    // 点击登录, 就会给服务器发起 http 请求 (可以使用 ajax 也可以使用 from 表单)
    // 在下一步 , 服务器要去处理一个登录请求, 读取 用户名密码, 在数据库中查询, 匹配, 如果正确, 就登录成功, 创建会话, 跳转到博客列表页
    // 由于这里, 登录成功, 直接进行重定向跳转,这种重定向操作, 就不需要浏览器写额外的代码, 直接浏览器自动跳转了
    // 1. 约定前后端交互接口
    //  请求 POST/login
    //      Content-Type: application/ x-www-form-urlencoded
    //      username=zhangsan&password=123
    //  响应  HTTP/1.1 302                      (form 表单提交成功之后 , 可以直接使用 302 进行跳转, 如果是 使用 ajax, 那就需要写代码才能进行跳转)
    //       Location: blog_list.html
    //
    // 2. 让前端发起请求
    // 3. 让服务器处理请求 并返回响应

    // 接下来实现强制要求登录功能
    //  在博客列表页, 详情页, 编辑页, 判定当前用户是否已经登录
    // 如果未登录, 则强制跳转到登录页(要求用户必须登陆后才能使用)
    // 只需要在呢几个页面中, 在页面加载时,给服务器发起一个ajax, 从服务器获取一下当前的登陆状态
    // 也就是在服务器中获取一下当前是否是登陆状态

    // 第一步 约定前后端交互接口(和前面一样)
    // 请求 :  GET /login
    // 响应 : 登陆成功: HTTP/1.1  200
    //        登录失败: HTTP/1.1 403
    //        也可以通过其他的方式 : 比如都是返回 200 , 但是在 body 中给不同的结果
    // 第二部: 控制前端代码, 让前端发起请求 (请求和响应部分一块写了)
    //   一个页面是可以触发 多个 ajax 的 , 这些 ajax 之间是 '并发执行的'效果, js 中 没有多线程这样的机制
    // 而 ajax 是一种特殊情况, 能够起到类似于 多线程 的效果
    // 相当于 同时发出去多个请求, 谁的响应先回来了那就先执行谁的

    // 接下来就是下一个功能: 显示用户信息
    // 博客列表页: 显示的是当前登录的用户信息
    // 博客详情页: 显示的是当前文章的作者信息

    // 在页面加载的时候 , 发起一个 ajax 请求
    // 服务器 返回对应的用户数据
    // 根据发起请求不同的页面, 服务器返回不同的信息即可
    // 1) 约定前后端交互接口
    //  博客列表页: 获取当前用户登录的信息
    //  请求 : GET/userInfo
    //  响应 : HTTP/1.1 200 OK
    //        application/json
    //          {
    //               userId:1
    //               username: 'zhangsan'
    //          }

    //  博客详情页: 获取当前文章的作者信息
    //  请求 : GET /authorInfo?blogId=1
    //  响应 : HTTP/1.1 200 OK
    //        application/json
    //          {
    //               userId:1
    //               username: 'zhangsan'
    //          }

    // 2) 先让前端代码发起这样的请求
    // 3) 编写服务器代码来处理上述请求
    // 4) 在前端代码中处理响应, 把响应数据写到对应的位置上


    // 下一个 功能 就是退出登录的功能
    // 在每一个导航栏中都有一个退出(注销)登录的 按钮
    // 注销是一个 a 标签 , 点击 会触发 http  请求, 会引起浏览器 跳转到另一个页面
    // 让用户点击 注销的时候 就会触发一个 http 请求,(GET请求), 服务器收到 Get 请求的时候 就会把 会话中的 user Attribute 给删了
    // 由于判定 用户登录状态的逻辑中, 需要同时验证, 会话存在, 且这里的 user Attribute 也存在, 只要破坏一个, 就可以使登录状态发生改变
    // 因为 servlet没有提供 删除 session 的方法
    // session 提供了一个 removeAttribute 这样的方法, 可以把 user 这个 Attribute 给删了
    // 1. 约定前后端交互接口
    //  请求 : GET/logout
    //  响应 : 直接重定向到博客登录页. HTTP/ 1.1 302
    //                             Location: login.html
    // 2. 编写前端代码,发送请求
    //    不用写 ajax . 直接给 a 标签 设置 href 属性即可
    // 3. 编写后端代码来处理这个请求, 完成退出登录的操作



    // 最后一个功能 就是 发布一个博客
    // 当我们点击提交的时候 就需要 构造一个 http 请求 , 把此时页面中的标题和正文 传输到服务器这边
    // 服务器把这个数据存入数据库中即可

    // 此处的 这里的 http 请求 可以使用 ajax 也可以 使用 form
    // 这种 填写输入框 提交数据的场景 使用 form 会更方便
    // 1. 前后端约定交互接口
    // 请求 : POST /blog
    //       Content-Type: x-www-form-urlencoded
    //       (body 部分)
    //       title=这是标题&content=这是正文
    //     (这些都是要进行 urlencoded 的 , 庆幸的是 form 表单都能直接完成这个操作)
    // 响应 : HTTP/1.1  302
    //       Location: blog_list.html
    // 2. 编写前端代码 构造请求
    //   (标题本身就是自己写的 input, 给他加上name 属性就很容易做到, 但是博客正文,是由 editormd 构成的编辑器, 那么如何构造成name 属性呢)
    //   editormd 的开发者们 也考虑到了这个情况
    // 在官方文档上也给出了一个例子, 在这个例子中告诉了我们具体如何将 editor md 和 form 表单配合使用
    // 3. 编写服务器代码 处理刚才的请求


}
